package com.baiyun.stock.service.Impl;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import com.baiyun.stock.constant.StockConstant;
import com.baiyun.stock.mapper.SysUserMapper;
import com.baiyun.stock.pojo.entity.SysUser;
import com.baiyun.stock.service.UserService;
import com.baiyun.stock.utils.IdWorker;
import com.baiyun.stock.vo.req.LoginReqVo;
import com.baiyun.stock.vo.resp.LoginRespVo;
import com.baiyun.stock.vo.resp.R;
import com.baiyun.stock.vo.resp.ResponseCode;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.junit.platform.commons.util.StringUtils;

import java.awt.*;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
@RequiredArgsConstructor
@Slf4j
public class UserServiceImpl implements UserService {

    private final SysUserMapper sysUserMapper;
    private final PasswordEncoder passwordEncoder;
    private  final RedisTemplate redisTemplate;
    private final IdWorker idWorker;

    /**
     * 根据用户名查询用户信息
     *
     * @param userName
     * @return
     */
    @Override
    public SysUser getUserByUserName(String userName) {
        return sysUserMapper.getUserByUserName(userName);
    }

    /**
     * 登录
     * @param vo
     * @return
     */
    @Override
    public R<LoginRespVo> login(LoginReqVo vo) {
        log.info("用户名：{}", vo.getUsername());
        //判断vo，username，和password是否为空
        if (vo == null || StringUtils.isBlank(vo.getUsername()) || StringUtils.isBlank(vo.getPassword())) {
            return R.error(ResponseCode.DATA_ERROR.getMessage());
        }

        //3.根据Rkey从redis中获取缓存的校验码
        String rCode= (String) redisTemplate.opsForValue().get(StockConstant.CHECK_PREFIX+vo.getSessionId());
        //判断获取的验证码是否存在，以及是否与输入的验证码相同        //忽略大小写差异
        if (StringUtils.isBlank(rCode) || ! rCode.equalsIgnoreCase(vo.getCode())) {
            //验证码输入有误
            return R.error(ResponseCode.CHECK_CODE_ERROR);
        }

        SysUser user = sysUserMapper.getUserByUserName(vo.getUsername());

        if (user == null) {
            return R.error(ResponseCode.USERNAME_OR_PASSWORD_ERROR.getMessage());
        }
        boolean matches = passwordEncoder.matches(vo.getPassword(), user.getPassword());
        if (matches == false){
            return R.error(ResponseCode.USERNAME_OR_PASSWORD_ERROR.getMessage());
        }

        LoginRespVo loginRespVo = new LoginRespVo();
        BeanUtils.copyProperties(user, loginRespVo);
        return R.ok(loginRespVo);
    }

    /**
     * 获取验证码
     * @return
     */
    @Override
    public R<Map> getCaptchaCode() {
        //参数分别是 宽、高、验证码长度、干扰线数量
        LineCaptcha captcha = CaptchaUtil.createLineCaptcha(250, 40, 4, 5);
        //设置背景颜色清灰
        captcha.setBackground(Color.lightGray);
        //获取图片中的验证码，默认生成的校验码包含文字和数字，长度为4
        String checkCode = captcha.getCode();
        //生成sessionId
        String sessionId = String.valueOf(idWorker.nextId());
        log.info("生成校验码:{},会话id为{}",checkCode,sessionId);
        //将sessionId和校验码保存在redis下，并设置缓存中数据存活时间一分钟
        redisTemplate.opsForValue().set(StockConstant.CHECK_PREFIX +sessionId,checkCode,5, TimeUnit.MINUTES);
        //将数据存到hash中存储，并返回前端
        Map info = new HashMap();
        info.put("sessionId", sessionId);
        info.put("imageDate", captcha.getImageBase64());

        return R.ok(info);
    }
}
